﻿#include "Map.h"
#include "ShareComponents.h"
#include "StaticObject.h"
#include "FWGraphic.h"
#include "Camera.h"
#include "Box.h"
#include "RSManager.h"
#include "Sprite.h"
#include "Bridge.h"
#include "GameDefine.h"
#include "Sniper.h"
#include "StandSniper.h"
#include "DefenseCannon.h"
#include "WallTurret.h"
#include "Cannon.h"
#include "Object.h"
#include "Boss.h"
#include "ScubaSoldier.h"
#include "Player.h"

Map::Map(SPRITE_ID id)
{	
	_objName = "";
	_sMap = RSManager::getInstance()->getSprite(id);
}

Map::~Map(void)
{
}

void Map::readMap(string fileName)
{		
	ifstream _mapStream;
	_mapStream.open(fileName, ios::in);
	if(!_mapStream.bad())
	{
		_mapStream>>this->_width;
		_mapStream>>this->_height;
		_arrMap = new int*[this->_height];
		for(int i = 0; i < this->_height; i++)
		{
			_arrMap[i] = new int[this->_width];
		}
		for(int j = 0; j < this->_height; j++)
		{
			for(int i = 0; i < this->_width; i++)			
			{				
				_mapStream>>_arrMap[j][i];				
			}
		}

		while(true)
		{
			_mapStream>>_objName;			
			if(_objName == "END")
				break;
			_mapStream>>_numObj;
			if(_numObj != 0)
			{
				if(_objName == "GROUND")
					readStaticObject(&_mapStream, GROUND);
				else
					if(_objName == "WATER")
						readStaticObject(&_mapStream, WATER);
				if(_objName == "BRIDGE")
					_lBridge = readListObjectPosition(&_mapStream);
				if(_objName == "SNIPER")
					_lSniper = readListObjectPosition(&_mapStream);
				if(_objName == "STANDSNIPER")
					_lStandSniper = readListObjectPosition(&_mapStream);
				if(_objName == "WALLTURRET")
					_lWallTurret = readListObjectPosition(&_mapStream);
				if(_objName == "CANNON")
					_lCannon = readListObjectPosition(&_mapStream);
				if(_objName == "DEFENSECANNON")
					_lDefenseCannon = readListObjectPosition(&_mapStream);
				if(_objName == "BOSS1")
					_lBoss = readListObjectPosition(&_mapStream);
				if (_objName == "SCUBASOLDIER")
					_lScubaSoldier = readListObjectPosition(&_mapStream);
				if(_objName == "PLAYER")
					_lPlayer = readListObjectPosition(&_mapStream);
				if(_objName == "BARRACKS")
					_lBarracks = readListObjectPosition(&_mapStream);
			}
		}
		_mapStream.close();	
	}
}

void Map::render()
{
	int vp_left = gl_camera->getLeftSide() / 32;
	int vp_right = gl_camera->getRightSide() / 32;
	for(int i = vp_left; i < vp_right; i++)
	{
		for(int j = 0; j < this->_height; j++)
		{						
			_sMap->Reset(_arrMap[j][i]-1);
			_sMap->Render(D3DXVECTOR2(i * 32, (_height - j - 1) * 32));
		}
	}	
}

list<StaticObject*> Map::getStaticObjects()
{	
	return _lStaticObj;
}

void Map::resetMap(int i, int j, int frame)	
{
	_arrMap[i][j] = frame;
}

list<Bridge*> Map::getStaticBridge()
{
	list<Bridge*> listBridge;
	Bridge* bridge;
	Box* box;
	D3DXVECTOR2 pos;
	D3DXVECTOR2 size;
	size.x = 64;
	size.y = 48;

	for (D3DXVECTOR2 pos : _lBridge)
	{
		box = new Box(pos - D3DXVECTOR2(0, 32), size, D3DXVECTOR2(0, 0));
		bridge = new Bridge(box);
		listBridge.push_back(bridge);
	}
	return listBridge;
}

list<D3DXVECTOR2> Map::readListObjectPosition(ifstream* stream)
{	
	D3DXVECTOR2 pos;
	list<D3DXVECTOR2> tmp;
	for (int i = 0; i < _numObj; i++)
	{
		*stream>>pos.x;
		*stream>>pos.y;
		tmp.push_back(pos);
	}
	return tmp;
}

list<Object*> Map::getObject()
{
	list<Object*> listObject;
	Cannon* e;	
	for(D3DXVECTOR2 pos : _lCannon)
	{
		e = new Cannon(new Box(pos, D3DXVECTOR2(66, 64), D3DXVECTOR2(0, 0)));
		e->init();
		listObject.push_back(e);
	}

	DefenseCannon* def;	
	int i = 0;
	for (D3DXVECTOR2 pos : _lDefenseCannon)
	{
		def = new DefenseCannon(new Box(pos, D3DXVECTOR2(0, 0), D3DXVECTOR2(0, 0)));
		def->init(i++);
		listObject.push_back(def);
	}

	Sniper* sniper;	
	for(D3DXVECTOR2 pos : _lSniper)
	{
		sniper = new Sniper(new Box(pos + D3DXVECTOR2(0, 16), D3DXVECTOR2(0, 0), D3DXVECTOR2(0, 0)));
		sniper->init();
		listObject.push_back(sniper);
	}

	StandSniper* standSniper;	
	for(D3DXVECTOR2 pos : _lStandSniper)
	{
		standSniper = new StandSniper(new Box(pos + D3DXVECTOR2(0, 16), D3DXVECTOR2(48, 78), D3DXVECTOR2(0, 0)));
		standSniper->init();
		listObject.push_back(standSniper);
	}

	WallTurret* wallTurret;	
	for (D3DXVECTOR2 pos : _lWallTurret)
	{
		wallTurret = new WallTurret(new Box(pos, D3DXVECTOR2(64, 64), D3DXVECTOR2(0, 0)));
		wallTurret->init();
		listObject.push_back(wallTurret);
	}

	Boss* b;	
	for(D3DXVECTOR2 pos : _lBoss)
	{
		b = new Boss(new Box(pos + D3DXVECTOR2(16, 0), D3DXVECTOR2(66, 64), D3DXVECTOR2(0, 0)));		
		listObject.push_back(b);
	}

	ScubaSoldier* scuba;
	for (D3DXVECTOR2 pos : _lScubaSoldier)
	{
		scuba = new ScubaSoldier(new Box(pos, D3DXVECTOR2(), D3DXVECTOR2()));
		listObject.push_back(scuba);
	}

	return listObject;
}

void Map::readStaticObject(ifstream* stream, STATIC_ID id)
{	
	StaticObject* st;
	int x, y, w, h;
	for(int i = 0; i < _numObj; i++)
	{
		*stream>>x;
		*stream>>y;
		*stream>>w;
		*stream>>h;						
		st = new StaticObject(new Box(D3DXVECTOR2(x, y), D3DXVECTOR2(w, h), D3DXVECTOR2(0, 0)), id);	
		_lStaticObj.push_back(st);		
	}	
}

int Map::getWidth()
{
	return _width;
}

int Map::getHeight()
{
	return _height;
}

list<D3DXVECTOR2> Map::getPlayer()
{
	return _lPlayer;
}

D3DXVECTOR2 Map::readObjectPosition(ifstream* stream)
{
	D3DXVECTOR2 pos;			
	*stream>>pos.x;
	*stream>>pos.y;			
	return pos;
}

list<D3DXVECTOR2> Map::getBarracks()
{
	return _lBarracks;
}
